package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLog;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLogConstant;
import com.cskaoyan.wordmemorize.converter.RolePermissionConverter;
import com.cskaoyan.wordmemorize.dao.entity.PermissionDO;
import com.cskaoyan.wordmemorize.dao.entity.RoleDO;
import com.cskaoyan.wordmemorize.dao.entity.RolePermissionDO;
import com.cskaoyan.wordmemorize.dao.mapper.PermissionMapper;
import com.cskaoyan.wordmemorize.dao.mapper.RoleMapper;
import com.cskaoyan.wordmemorize.dao.mapper.RolePermissionMapper;
import com.cskaoyan.wordmemorize.dto.admin.*;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.request.PermissionCommand;
import com.cskaoyan.wordmemorize.request.RoleCommand;
import com.cskaoyan.wordmemorize.request.RolePermissionCommand;
import com.cskaoyan.wordmemorize.service.RolePermissionService;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Service
public class RolePermissionServiceImpl implements RolePermissionService {

    @Autowired
    PermissionMapper permissionMapper;

    @Autowired
    RolePermissionConverter rolePermissionConverter;

    @Autowired
    RoleMapper roleMapper;

    @Override
    //@OperateLog(dateType = "权限", operateType = OperateLogConstant.OPERATE_ADD)
    public void savePermissions(PermissionCommand command) {
        PermissionDO permissionDO = rolePermissionConverter.command2PermissionDO(command);
        permissionMapper.insert(permissionDO);
    }

    @Override
    public List<PermissionDTO> getPermissions() {
        //获取父Id为-1的权限列表
        List<PermissionDO> permissionDOS = permissionMapper.selectList(new QueryWrapper<PermissionDO>().eq("parent_permission", -1));
        List<PermissionDTO> permissionDTOS = rolePermissionConverter.employeePermissionDO2DTO(permissionDOS);
        //获取子权限列表
        for (PermissionDTO permissionDTO : permissionDTOS) {
            List<PermissionDO> permissionDOS1 = permissionMapper.selectList(new QueryWrapper<PermissionDO>().eq("parent_permission", permissionDTO.getId()));
            permissionDTO.setChildren(rolePermissionConverter.employeePermissionDO2DTO(permissionDOS1));
            for (PermissionDTO permissionDTO1 : permissionDTO.getChildren()) {
                List<PermissionDO> permissionDOS2 = permissionMapper.selectList(new QueryWrapper<PermissionDO>().eq("parent_permission", permissionDTO1.getId()));
                permissionDTO1.setChildren(rolePermissionConverter.employeePermissionDO2DTO(permissionDOS2));
            }
        }
        return permissionDTOS;
    }

    @Override
    //@OperateLog(dateType = "权限", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeletePermissionOperateDTO deletePermission(Long permissionId) {
        PermissionDO permissionDO = permissionMapper.selectById(permissionId);
        //日志对象
        DeletePermissionOperateDTO deletePermissionOperateDTO =
                rolePermissionConverter.toDeletePermissionOperateDTO(permissionDO);

        int id = permissionMapper.deleteById(permissionId);

        return deletePermissionOperateDTO;
    }

    @Override
    //@OperateLog(dateType = "权限", operateType = OperateLogConstant.OPERATE_UPDATE)
    public void updatePermission(PermissionCommand command) {
        PermissionDO permissionDO = rolePermissionConverter.command2PermissionDO(command);
        permissionMapper.updateById(permissionDO);
    }

    @Override
    public PageDTO<RoleDTO> getRoleList(PageRequest pageRequest) {
        Integer pageNum = pageRequest.getPageNum();
        Integer count = pageRequest.getCount();
        String keyword = pageRequest.getKeyword();
        if (pageNum == null) {
            List<RoleDO> roleDOS = roleMapper.selectList(null);
            return rolePermissionConverter.roleList2Page(roleDOS, (long) roleDOS.size());
        }
        Page<RoleDO> pageParams = new Page(pageNum,count);
        if(keyword == null ){
            // 不带关键词的查询
            Page<RoleDO> roleDOPage = roleMapper.selectPage(pageParams, null);
            return rolePermissionConverter.roleList2Page(roleDOPage.getRecords(), roleDOPage.getTotal());
        }
        LambdaQueryWrapper<RoleDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(RoleDO::getName,keyword);

        Page<RoleDO> roleDOPage = roleMapper.selectPage(pageParams, queryWrapper);
        return rolePermissionConverter.roleList2Page(roleDOPage.getRecords(),roleDOPage.getTotal());
    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_ADD)
    public void addRole(RoleCommand command) {
        RoleDO roleDO = rolePermissionConverter.command2RoleDO(command);
        roleMapper.insert(roleDO);
    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_UPDATE)
    public void updateRole(RoleCommand roleCommand) {
        RoleDO roleDO = rolePermissionConverter.command2RoleDO(roleCommand);
        roleMapper.updateById(roleDO);
    }


    @Autowired
    RolePermissionMapper rolePermissionMapper;

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_UPDATE)
    public void updateRolePermission(RolePermissionCommand command) {
        String roleId = command.getRoleId();
        List<String> permissions = command.getPermissions();

        // 更新role_permission
        for (String permission:permissions) {
            //根据角色id 和权限id查询数据库 该角色是否已经有这个权限
            LambdaQueryWrapper<RolePermissionDO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(RolePermissionDO::getRoleId,roleId)
                            .eq(RolePermissionDO::getPermissionId,permission);
            RolePermissionDO one = rolePermissionMapper.selectOne(wrapper);
            if(one == null){
                // role_permission 表中没有权限 分为2种情况（1.没有记录 2.有记录但是被逻辑删除）
                // 判断是否是逻辑删除
                RolePermissionDO exist =
                        rolePermissionMapper.selectOne(wrapper.setEntity(new RolePermissionDO()));
                if(exist == null){
                    RolePermissionDO rolePermissionDO = new RolePermissionDO();
                    rolePermissionDO.setRoleId(Long.valueOf(roleId));
                    rolePermissionDO.setPermissionId(Long.valueOf(permission));
                    rolePermissionMapper.insert(rolePermissionDO);
                }else{
                    exist.setIsDeleted(0);
                    rolePermissionMapper.updateById(exist);
                }

            }
            // 已存在，且未删除  不做操作
        }
    }

    // 获取角色对应的授权信息
    @Override
    public RolePermissionDTO getRolePermissionList(Long roleId) {

        // 获取系统权限
        List<PermissionDTO> permissions = this.getPermissions();

        // 获取角色已授权的权限
        LambdaQueryWrapper<RolePermissionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermissionDO::getRoleId,roleId);
        List<RolePermissionDO> rolePermissionDOs = rolePermissionMapper.selectList(wrapper);

        List<String> assignedPermissions = new ArrayList<>();
        for (RolePermissionDO rolePermissionDO : rolePermissionDOs) {
            // 排除 根节点的权限
            Long permissionId = rolePermissionDO.getPermissionId();
            PermissionDO permissionDO = permissionMapper.selectById(permissionId);

            if(permissionDO!= null && permissionDO.getPermissionType() == 2){
                assignedPermissions.add(String.valueOf(rolePermissionDO.getPermissionId()));
            }
        }

        // 返回
        RolePermissionDTO rolePermissionDTO = new RolePermissionDTO();
        rolePermissionDTO.setSystemPermissions(permissions);
        rolePermissionDTO.setAssignedPermissions(assignedPermissions);
        return rolePermissionDTO;
    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteRoleOperateDTO deleteRole(Long roleId) {
        RoleDO roleDO = roleMapper.selectById(roleId);
        roleMapper.deleteById(roleId);
        return rolePermissionConverter.toDeleteRoleOperateDTO(roleDO);
    }

    @Override
    @OperateLog(dateType = "角色", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    public DeleteRolePermissionOperateDTO deleteRolePermission(Long roleId, Long permissionId) {
        // 角色权限取消时的操作

        //1.删除role_permission
        LambdaQueryWrapper<RolePermissionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermissionDO::getRoleId,roleId)
                .eq(RolePermissionDO::getPermissionId,permissionId);
        RolePermissionDO one = rolePermissionMapper.selectOne(wrapper);
        if(one != null){
            rolePermissionMapper.deleteById(one.getId());
        }

        // 查看是否有子权限
        LambdaQueryWrapper<PermissionDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PermissionDO::getParentPermission, permissionId);
        List<PermissionDO> permissionDOS = permissionMapper.selectList(lambdaQueryWrapper);
        if(permissionDOS.isEmpty()){
            return null;
        }
        else {
            for (PermissionDO permissionDO : permissionDOS) {
                deleteRolePermission(roleId, permissionDO.getId());
            }
        }

        RoleDO roleDO = roleMapper.selectById(roleId);
        PermissionDO permissionDO = permissionMapper.selectById(permissionId);
        rolePermissionMapper.deleteById(permissionId);
        return rolePermissionConverter.toDeleteRolePermissionOperateDTO(roleDO,permissionDO);
    }

    @Override
    public int insert(PermissionDO entity) {
        return 0;
    }

    @Override
    public int deleteById(PermissionDO entity) {
        return 0;
    }

    @Override
    public int delete(Wrapper<PermissionDO> queryWrapper) {
        return 0;
    }

    @Override
    public int updateById(PermissionDO entity) {
        return 0;
    }

    @Override
    public int update(PermissionDO entity, Wrapper<PermissionDO> updateWrapper) {
        return 0;
    }

    @Override
    public PermissionDO selectById(Serializable id) {
        return null;
    }

    @Override
    public List<PermissionDO> selectByIds(Collection<? extends Serializable> idList) {
        return null;
    }

    @Override
    public void selectByIds(Collection<? extends Serializable> idList, ResultHandler<PermissionDO> resultHandler) {

    }

    @Override
    public Long selectCount(Wrapper<PermissionDO> queryWrapper) {
        return null;
    }

    @Override
    public List<PermissionDO> selectList(Wrapper<PermissionDO> queryWrapper) {
        return null;
    }

    @Override
    public void selectList(Wrapper<PermissionDO> queryWrapper, ResultHandler<PermissionDO> resultHandler) {

    }

    @Override
    public List<PermissionDO> selectList(IPage<PermissionDO> page, Wrapper<PermissionDO> queryWrapper) {
        return null;
    }

    @Override
    public void selectList(IPage<PermissionDO> page, Wrapper<PermissionDO> queryWrapper, ResultHandler<PermissionDO> resultHandler) {

    }

    @Override
    public List<Map<String, Object>> selectMaps(Wrapper<PermissionDO> queryWrapper) {
        return null;
    }

    @Override
    public void selectMaps(Wrapper<PermissionDO> queryWrapper, ResultHandler<Map<String, Object>> resultHandler) {

    }

    @Override
    public List<Map<String, Object>> selectMaps(IPage<? extends Map<String, Object>> page, Wrapper<PermissionDO> queryWrapper) {
        return null;
    }

    @Override
    public void selectMaps(IPage<? extends Map<String, Object>> page, Wrapper<PermissionDO> queryWrapper, ResultHandler<Map<String, Object>> resultHandler) {

    }

    @Override
    public <E> List<E> selectObjs(Wrapper<PermissionDO> queryWrapper) {
        return null;
    }

    @Override
    public <E> void selectObjs(Wrapper<PermissionDO> queryWrapper, ResultHandler<E> resultHandler) {

    }
}
